<?php

namespace nimo\domains\acc\batch\csv;

use DB;
use DateTime;
use nimo\common\csv\CsvConverter;
use nimo\common\csv\Importer;
use nimo\common\csv\SimpleConverter;
use nimo\common\csv\SimpleInterceptor;
use nimo\common\validator\BatchValidator;
use nimo\common\models\SequenceGenerator;
use nimo\domains\acc\validator\BooksValidator;
use File;

class WakuDataCsvImportConverter {
    protected $file = null;
    protected $configs = null;
    protected $validator = null;
    protected $converter = null;
    protected $simpleInterceptor = null;
    protected $_resources = null;
    public function __construct($file, BatchValidator $validator, CsvConverter $converter, $configs = array()) {
        if (! isset($configs['domain'])) {
            throw new \Exception("make sure your domain");
        }
        if (! file_exists($file)) {
            throw new \Exception("make sure your $file");
        }
        $this->file = realpath($file);
        $this->validator = $validator;
        $this->converter = $converter;
        $this->configs = $configs;
    }
    public static function import($file, $params = array()) {
        $resources = File::getRequire(__DIR__ . '/WakuDataCsvConfig.php');
        $validators = $resources['validators'];
        $converters = $resources['converters'];
        $params = $params + array('skipFirst' => true,'fromCharset' => 'MS932');
        $validator = new BatchValidator(array_values($validators));
        $converter = new SimpleConverter($converters);
        $importer = new WakuDataCsvImportConverter($file, $validator, $converter, $params);
        $importer->_resources = $resources;
        return $importer->execute();
    }
    public function execute() {
        // read file & keep data in si
        $si = new SimpleInterceptor($this->validator, $this->converter, $this->configs);
        $ci = new Importer($this->file, $this->configs, $si);
        $ci->execute();
        if (count($messages = $si->messages())) {
            return array('csv' => $messages);
        }
        $datas = $si->getDatas();
        // replace & format
        $this->replaceDatas($datas);
        // validate
        $result = null;
        $booksValidator = new BooksValidator($datas, array('ym' => $this->configs['batch_ym']));
        if (! $booksValidator->passes()) {
            $result= array('books' => $booksValidator->getMessageBag()->all());
        }
        // insert into database
        $this->insertData($datas);
        return $result;
    }
    public static function getStringSize($value) {
        if (function_exists('mb_strlen'))
            return mb_strlen($value);
        return strlen($value);
    }
    protected function replaceDatas(array &$datas) {
        $mappings = $this->_resources['mappings'];
        foreach ( $datas as &$d ) {
            foreach ( $d as $k => $v ) {
                if ($v == '') {
                    $d[$k] = null;
                    continue;
                }
                if (array_key_exists($k, $mappings)) {
                    $a = $mappings[$k];
                    if (array_key_exists($v, $a)) {
                        $d[$k] = $a[$v];
                    }
                }
            }
            $size = static::getStringSize($d['summary']);
            if ($size > 40) {
                $d['memo'] = $d['summary'];
                $d['summary'] = mb_strcut($d['summary'], 0, 40);
            }
            if (preg_match('/^(\d+)\s+(.*)/i', $d['tag'], $m)) {
                $d['tag'] = $m[1];
                $d['memo'] .= $m[2];
            }
        }
    }
    protected function insertData(array $datas) {
        DB::transaction(function () use($datas) {

            $table = 'acc_book';
            $ym = $this->configs['batch_ym'];
            $domain = $this->configs['domain'];




            if (isset($this->configs['batch_no'])) {
                $no = $this->configs['batch_no'];
                DB::delete( DB::raw("delete from acc_book where domain=:domain and ym=:ym and batch=:batch"), array('domain' => $domain,'ym' => $ym,'batch' => $no));
            } else {
                $seq = SequenceGenerator::current($table, array('domain' => $domain,'ym' => $ym));
                $no = $seq->nextval();
            }
            $now = new DateTime();
            $seq = 1;
            foreach ( $datas as &$d ) {
                $d['domain'] = $domain;
                $d['id'] = $no;
                $d['seq'] = $seq ++;
                $d['history'] =null;
                $d['batch'] = $no;
                if (empty($d['create_user'])) {
                    $d['create_user'] = 'system';
                }
                if (empty($d['update_user'])) {
                    $d['update_user'] = 'system';
                }
                $d['created_at'] = $now;
                $d['updated_at'] = $now;
                DB::table($table)->insert($d);
            }
        });
    }
}

/*

php artisan app:domain acc book --path=./app/lib/src  --fields=./app/lib/stubs/nd/20140428_acc_tbook_table.txt --forced=on --nameprefix=no && php artisan migrate --path=.\app\lib\src\nimo\database\migrations && pause && php ./app/temp/batch.php

acc/master/code
acc/journal/entry

        '伝票連番' => 'required|digits_between:1,6',          // 0
        '伝票日付' => 'required|dateFormat:Y/m/d',            // 1
        '曜日' => null,                                       // 2
        '伝票番号' => 'required|digits_between:1,4',          // 5
        '仕訳連番' => 'required|digits_between:1,4',          // 10

acc_mcode
acc_scode
tbook_info


 *
 */
